package com.iscas.loadstorm.isloadstorm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.iscas.loadstorm.isloadstorm.domain.Load;
import com.iscas.loadstorm.isloadstorm.domain.LoadApi;
import com.iscas.loadstorm.isloadstorm.domain.LoadScript;
import com.iscas.loadstorm.isloadstorm.domain.TestRun;
import com.iscas.loadstorm.isloadstorm.mapper.LoadApiMapper;
import com.iscas.loadstorm.isloadstorm.mapper.LoadMapper;
import com.iscas.loadstorm.isloadstorm.mapper.LoadScriptMapper;
import com.iscas.loadstorm.isloadstorm.service.LoadService;
import com.iscas.loadstorm.isloadstorm.util.ApiRunner;
import com.iscas.loadstorm.isloadstorm.util.JmxRunner;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
* @author mj
* @description 针对表【load】的数据库操作Service实现
* @createDate 2024-12-24 10:22:05
*/
@Service
public class LoadServiceImpl extends ServiceImpl<LoadMapper, Load>
        implements LoadService {

    @Autowired
    private LoadScriptMapper loadscriptMapper;

    @Autowired
    private LoadApiMapper loadApiMapper;

    @Autowired
    private JmxRunner jmxRunner;

    @Autowired
    private ApiRunner apiRunner;

    @Value("${jmeter.home}")
    private String jmeterHome;

    @Override
    public String runLoadTest(String loadId) {
        // 查询load信息
        Load load = this.getById(loadId);
        if (load == null) {
            throw new RuntimeException("Load not found with id: " + loadId);
        }

        // 根据类型选择不同的测试方式
        if (load.getType() == 1) {
            // 脚本类型测试
            return runScriptTest(loadId);
        } else if (load.getType() == 2) {
            // API类型测试
            return runApiTest(loadId);
        } else {
            throw new RuntimeException("Invalid load type: " + load.getType());
        }
    }

    /**
     * 运行脚本类型测试
     */
    private String runScriptTest(String loadId) {
        // 查询脚本信息
        LambdaQueryWrapper<LoadScript> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LoadScript::getLoadId, loadId)
                .eq(LoadScript::getIsDelete, 0);

        LoadScript loadScript = loadscriptMapper.selectOne(wrapper);
        if (loadScript == null) {
            throw new RuntimeException("Load script not found for load id: " + loadId);
        }

        // 运行JMX测试
        return jmxRunner.runJMeterTest(loadScript.getLoadScriptUrl());
    }

    /**
     * 运行API类型测试
     */
    private String runApiTest(String loadId) {
        // 查询API信息
        LambdaQueryWrapper<LoadApi> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LoadApi::getLoadId, loadId)
                .eq(LoadApi::getIsDelete, 0);

        LoadApi loadApi = loadApiMapper.selectOne(wrapper);
        if (loadApi == null) {
            throw new RuntimeException("Load API not found for load id: " + loadId);
        }

        // 运行API测试
        return apiRunner.runApiTest(loadApi, jmeterHome);
    }


    /**
     * 获取测试状态
     */
    @Override
    public Map<String, Object> getTestStatus(String testId) {
        TestRun testRun = jmxRunner.getTestRun(testId);
        if (testRun == null) {
            testRun = apiRunner.getTestRun(testId);
            if (testRun == null) {
                throw new RuntimeException("Test not found with id: " + testId);
            }
        }

        Map<String, Object> status = new HashMap<>();
        status.put("testId", testId);
        status.put("samples", testRun.getSamples());
        status.put("errors", testRun.getErrors());

        // 计算错误率
        double errorRate = testRun.getSamples() > 0
                ? (double) testRun.getErrors() / testRun.getSamples() * 100
                : 0;
        status.put("errorRate", String.format("%.2f%%", errorRate));

        return status;
    }


    @Override
    public void stopTest(String testId) {
        // 尝试从JmxRunner中获取测试
        TestRun testRun = JmxRunner.getTestRun(testId);
        boolean isJmxTest = true;

        // 如果不是JMX测试，尝试从ApiRunner中获取
        if (testRun == null) {
            testRun = ApiRunner.getTestRun(testId);
            isJmxTest = false;
            if (testRun == null) {
                throw new RuntimeException("Test not found with id: " + testId);
            }
        }

        // 停止JMeter引擎
        try {
            StandardJMeterEngine engine = testRun.getEngine();
            if (engine != null) {
                engine.stopTest(true);
            }

            // 从相应的Map中移除测试记录
            if (isJmxTest) {
                JmxRunner.stopTest(testId);
            } else {
                ApiRunner.stopTest(testId);
            }
        } catch (Exception e) {
            throw new RuntimeException("Failed to stop test: " + e.getMessage());
        }
    }
}


